import re
import dash
from dash import html, dcc
import feffery_antd_components as fac
from dash.dependencies import Input, Output, State, MATCH

demo_config = {
    '字段1': {
        '名称': 'field1',
        '类型': 'input',
        '验证': '^\d[8]$',
        '说明': '这是字段1'
    },
    '字段2': {
        '名称': 'field2',
        '类型': 'input',
        '验证': '^([1-9]\d*|0)(\.\d{1,2})?$',
        '说明': '这是字段2'
    },
    '字段3': {
        '名称': 'field3',
        '类型': 'select',
        '验证': '^(\w)+$',
        '说明': '这是字段3',
        'options': [
            {'label': '0--北京', 'value': '0'},
            {'label': '1--上海', 'value': '1'},
            {'label': '2--广东', 'value': '2'}
        ]
    }
}

type2component = {
    'input': fac.AntdInput,
    'select': fac.AntdSelect
}

app = dash.Dash(
    __name__,
    suppress_callback_exceptions=True
)


app.layout = html.Div(
    [
        fac.AntdButton(
            '生成modal表单',
            id='generate-modal',
            type='primary'
        ),

        fac.AntdModal(
            id='modal-form'
        )
    ],
    style={
        'padding': '50px'
    }
)


@app.callback(
    [Output('modal-form', 'children'),
     Output('modal-form', 'visible')],
    Input('generate-modal', 'nClicks')
)
def generate_form_via_params(nClicks):

    if nClicks:

        # 假装从接口取得当前字段参数数据
        ...
        config = demo_config

        return [
            [
                fac.AntdForm(
                    [
                        *[
                            fac.AntdFormItem(
                                [
                                    type2component.get(config_item['类型'])(
                                        id={
                                            'type': 'field',
                                            'index': i
                                        },
                                        placeholder=config_item['说明'],
                                        **{
                                            key: value
                                            for key, value in config_item.items()
                                            if key not in ['名称', '类型', '验证', '说明']
                                        },
                                        style={
                                            'width': '100%'
                                        }
                                    ),
                                    dcc.Store(
                                        id={
                                            'type': 'parameters',
                                            'index': i
                                        },
                                        data=config_item
                                    )
                                ],
                                id={
                                    'type': 'field-form-item',
                                    'index': i
                                },
                                label=config_item['名称']
                            )
                            for i, config_item in enumerate(config.values())
                        ],
                        fac.AntdButton(
                            '提交',
                            id='submit-form',
                            type='primary',
                            style={
                                'float': 'right'
                            }
                        )
                    ],
                    style={
                        'padding': '50px'
                    }
                )
            ],
            True
        ]

    return None, False


@app.callback(
    [
        Output(
            {
                'type': 'field-form-item',
                'index': MATCH
            },
            'validateStatus'
        ),
        Output(
            {
                'type': 'field-form-item',
                'index': MATCH
            },
            'help'
        )
    ],
    Input(
        {
            'type': 'field',
            'index': MATCH
        },
        'value'
    ),
    State(
        {
            'type': 'parameters',
            'index': MATCH
        },
        'data'
    )
)
def validate_field_input(value, data):

    if value:

        if re.match(data['验证'], value):
            return 'success', None

        else:
            return 'error', '格式非法'

    return None, '请输入'


if __name__ == '__main__':
    app.run(debug=True)
